﻿#include "VAOneXMLAdaptorMaterial.h"
#include "rapidxml.hpp"
#include "FITKAcousticsPhysics/FITKAcousticsPhysics.h"
#include "FITKAcousticsPhysics/FITKAcousticsMaterialsFluid.h"
#include "FITKAcousticsPhysics/FITKAcousticsMaterialsFoam.h"
#include "FITKAcousticsPhysics/FITKAcousticsMaterialsFiber.h"
#include "FITKAcousticsPhysics/FITKAcousticsMaterialsIsosolid.h"
#include "FITKAcousticsPhysics/FITKAcousticsMaterialsViscoElastic.h"
#include "FITKAcousticsPhysics/FITKAcousticsAbsMaterial.h"
#include "FITK_Kernel/FITKAppFramework/FITKAppFramework.h"
#include "FITK_Kernel/FITKAppFramework/FITKGlobalData.h"
#include "VAOneXMLAdaptorMaterialFluid.h"
#include "VAOneXMLAdaptorMaterialFoam.h"
#include "VAOneXMLAdaptorMaterialFiber.h"
#include "VAOneXMLAdaptorMaterialIsosolid.h"
#include "VAOneXMLAdaptorMaterialViscoElastic.h"

namespace IO
{
    bool VAOneXMLAdaptorMaterial::adaptR()
    {
        // 指针判断是否为空
        if(!_node) return false;

        if(!_dataObj) return false;

        _materialsManager = dynamic_cast<Acoustics::FITKAcousticsMaterialManager*>(_dataObj);

        if(!_materialsManager) return false;

        bool b = true;
        // 读取流体材料
        b &= readMaterialFluid();
        // 读取泡沫材料
        b &= readMaterialFoam();
        // 读取纤维材料
        b &= readMaterialFiber();
        // 读取各向同性固体材料
        b &= readMaterialIsosolid();
        // 读取粘弹性材料
        b &= readMaterialViscoElasticMaterial();
        // 返回操作是否成功
        return b;
    }

    bool VAOneXMLAdaptorMaterial::adaptW()
    {
        // 指针判断是否为空
        if(!_node) return false;

        if(!_dataObj) return false;

        _materialsManager = dynamic_cast<Acoustics::FITKAcousticsMaterialManager*>(_dataObj);

        if(!_materialsManager) return false;

        bool b = true;
        // 写入流体材料
        b &= writeMaterialFluid();
        // 写入泡沫材料
        b &= writeMaterialFoam();
        // 写入纤维材料
        b &= writeMaterialFiber();
        // 写入各向同性固体材料
        b &= writeMaterialIsosolid();
        // 写入粘弹性材料
        b &= writeMaterialViscoElasticMaterial();
        // 返回操作是否成功
        return b;
    }

    bool VAOneXMLAdaptorMaterial::readMaterialFluid()
    {    
        rapidxml::xml_node<char>* node = _node->first_node("Fluid");

        // 判断Fluid节点是否存在
        if (!node) return true;

        bool b = true;

        IO:: VAOneXMLAdaptorMaterialFluid* adaptor{};
        // 循环处理每个Fluid节点数据
        while (node)
        {
            Acoustics::FITKAcousticsMaterialsFluid* mData = new Acoustics::FITKAcousticsMaterialsFluid;
            if(!adaptor)
            {
                adaptor = FITKIOADAPTORFACTORY->createT<IO::VAOneXMLAdaptorMaterialFluid>("VAOneXML", mData);
                if(!adaptor)
                {
                    delete mData;
                    mData = nullptr;
                    //读写器创建异常
                    consoleMessage(3,"create Fluid adaptor Error");
                    return false;
                }
            }

            adaptor->setNode(node);
            adaptor->setDataObject(mData);
            b &= adaptor->adaptR();

            //根据名称获取对象
            auto m = _materialsManager->getDataByName(mData->getDataObjectName());
            if(!m)
            {
                //返回为空 插入mData
                _materialsManager->appendDataObj(mData);
            }
            else
            {
                //返回不为空， 覆盖数据
                m->copy(mData);
                delete mData;
            }
            node = node->next_sibling("Fluid");
        }

        delete adaptor;
        adaptor = nullptr;
        //读取成功
        return b;
    }

    bool VAOneXMLAdaptorMaterial::writeMaterialFluid()
    {
        // 获取流体材料列表
        auto FITKAcousticsMaterials = _materialsManager->getAcousticsMaterials(Acoustics::FITKAcousticsAbsMaterial::Fluid);
        bool b = true;
        // 使用适配器写入数据
        IO::VAOneXMLAdaptorMaterialFluid* adaptor{};

        // 循环处理每个材料
        for (const auto& material : FITKAcousticsMaterials)
        {
            if (!material) continue;

            if(!adaptor)
            {
                adaptor = FITKIOADAPTORFACTORY->createT<IO::VAOneXMLAdaptorMaterialFluid>("VAOneXML", material);
                if (!adaptor)
                {
                    // 适配器创建失败，输出错误信息并返回失败
                    consoleMessage(3, "create Fluid adaptor Error");
                    return false;
                }
            }

            // 创建流体节点
            rapidxml::xml_node<char>* node = createNodeElement(_node, "Fluid");
            adaptor->setNode(node);
            adaptor->setDataObject(material);
            // 执行数据写入
            b &= adaptor->adaptW();
        }

        delete adaptor;
        adaptor = nullptr;
        // 返回操作成功的状态
        return b;
    }

    bool VAOneXMLAdaptorMaterial::readMaterialFoam()
    {
        rapidxml::xml_node<char>* node = _node->first_node("Foam");

        // 判断节点是否存在
        if (!node) return true;

        bool b = true;
        IO:: VAOneXMLAdaptorMaterialFoam* adaptor{};

        // 循环处理每个节点数据
        while (node)
        {
            Acoustics::FITKAcousticsMaterialsFoam* mData = new Acoustics::FITKAcousticsMaterialsFoam;
            if(!adaptor)
            {
                adaptor = FITKIOADAPTORFACTORY->createT<IO::VAOneXMLAdaptorMaterialFoam>("VAOneXML", mData);
                if(!adaptor)
                {
                    delete mData;
                    mData = nullptr;
                    //读写器创建异常
                    consoleMessage(3,"create Foam adaptor Error");
                    return false;
                }
            }

            adaptor->setNode(node);
            adaptor->setDataObject(mData);
            b &= adaptor->adaptR();
            //根据名称获取对象
            auto m = _materialsManager->getDataByName(mData->getDataObjectName());

            if(!m)
            {
                //返回为空 插入mData
                _materialsManager->appendDataObj(mData);
            }
            else
            {
                //返回不为空， 覆盖数据
                m->copy(mData);
                delete mData;
            }

            node = node->next_sibling("Foam");
        }

        delete adaptor;
        adaptor = nullptr;
        //读取成功
        return b;
    }

    bool VAOneXMLAdaptorMaterial::writeMaterialFoam()
    {
        // 获取泡沫材料列表
        auto FITKAcousticsMaterials = _materialsManager->getAcousticsMaterials(Acoustics::FITKAcousticsAbsMaterial::Foam);
        bool b = true;
        IO:: VAOneXMLAdaptorMaterialFoam* adaptor{};

        // 循环处理每个材料
        for (const auto& material : FITKAcousticsMaterials)
        {
            if (!material) continue;

            // 使用适配器写入数据
            if(!adaptor)
            {
                adaptor = FITKIOADAPTORFACTORY->createT<IO::VAOneXMLAdaptorMaterialFoam>("VAOneXML", material);
                if (!adaptor)
                {
                    // 适配器创建失败，输出错误信息并返回失败
                    consoleMessage(3, "create Foam adaptor Error");
                    return false;
                }
            }

            // 创建泡沫节点
            rapidxml::xml_node<char>* node = createNodeElement(_node, "Foam");
            adaptor->setNode(node);
            adaptor->setDataObject(material);
            // 执行数据写入
            b &= adaptor->adaptW();
        }

        delete adaptor;
        adaptor = nullptr;
        // 返回操作成功的状态
        return b;
    }

    bool VAOneXMLAdaptorMaterial::readMaterialFiber()
    {
        rapidxml::xml_node<char>* node = _node->first_node("Fiber");

        // 判断节点是否存在
        if (!node) return true;

        bool b = true;
        IO:: VAOneXMLAdaptorMaterialFiber* adaptor{};

        // 循环处理每个Fluid节点数据
        while (node)
        {
            Acoustics::FITKAcousticsMaterialsFiber* mData = new Acoustics::FITKAcousticsMaterialsFiber;

            if(!adaptor)
            {
                adaptor = FITKIOADAPTORFACTORY->createT<IO::VAOneXMLAdaptorMaterialFiber>("VAOneXML", mData);
                if(!adaptor)
                {
                    delete mData;
                    mData = nullptr;
                    //读写器创建异常
                    consoleMessage(3, "create Fiber adaptor Error");
                    return false;
                }
            }

            adaptor->setNode(node);
            adaptor->setDataObject(mData);
            b &= adaptor->adaptR();
            //根据名称获取对象
            auto m = _materialsManager->getDataByName(mData->getDataObjectName());
            if(!m)
            {
                //返回为空 插入mData
                _materialsManager->appendDataObj(mData);
            }
            else
            {
                //返回不为空， 覆盖数据
                m->copy(mData);
                delete mData;
            }

            node = node->next_sibling("Fiber");
        }

        delete adaptor;
        adaptor = nullptr;
        //读取成功
        return b;
    }

    bool VAOneXMLAdaptorMaterial::writeMaterialFiber()
    {
        // 获取纤维材料列表
        auto FITKAcousticsMaterials = _materialsManager->getAcousticsMaterials(Acoustics::FITKAcousticsAbsMaterial::Fiber);
        bool b = true;
        IO:: VAOneXMLAdaptorMaterialFiber* adaptor{};

        // 循环处理每个材料
        for (const auto& material : FITKAcousticsMaterials)
        {
            if (!material) continue;

            // 使用适配器写入数据
            if(!adaptor)
            {
                adaptor = FITKIOADAPTORFACTORY->createT<IO::VAOneXMLAdaptorMaterialFiber>("VAOneXML", material);
                if (!adaptor)
                {
                    // 适配器创建失败，输出错误信息并返回失败
                    consoleMessage(3, "create Fiber adaptor Error");
                    return false;
                }
            }

            // 创建纤维节点
            rapidxml::xml_node<char>* node = createNodeElement(_node, "Fiber");
            adaptor->setNode(node);
            adaptor->setDataObject(material);
            // 执行数据写入
            b &= adaptor->adaptW();
        }

        delete adaptor;
        adaptor = nullptr;
        // 返回操作成功的状态
        return b;
    }

    bool VAOneXMLAdaptorMaterial::readMaterialIsosolid()
    {
        rapidxml::xml_node<char>* node = _node->first_node("Isosolid");

        // 判断节点是否存在
        if (!node) return true;

        bool b = true;
        IO:: VAOneXMLAdaptorMaterialIsosolid* adaptor{};

        // 循环处理每个节点数据
        while (node)
        {
            Acoustics::FITKAcousticsMaterialsIsosolid* mData = new Acoustics::FITKAcousticsMaterialsIsosolid;

            if(!adaptor)
            {
                adaptor = FITKIOADAPTORFACTORY->createT<IO::VAOneXMLAdaptorMaterialIsosolid>("VAOneXML", mData);
                if(!adaptor)
                {
                    delete mData;
                    mData = nullptr;
                    //读写器创建异常
                    consoleMessage(3, "create Isosolid adaptor Error");
                    return false;
                }
            }

            adaptor->setNode(node);
            adaptor->setDataObject(mData);
            b &= adaptor->adaptR();

            //根据名称获取对象
            auto m = _materialsManager->getDataByName(mData->getDataObjectName());
            if(!m)
            {
                //返回为空 插入mData
                _materialsManager->appendDataObj(mData);
            }
            else
            {
                //返回不为空， 覆盖数据
                m->copy(mData);
                delete mData;
            }

            node = node->next_sibling("Isosolid");
        }

        delete adaptor;
        adaptor = nullptr;
        //读取成功
        return b;
    }

    bool VAOneXMLAdaptorMaterial::writeMaterialIsosolid()
    {
        // 获取各向同性固体材料列表
        auto FITKAcousticsMaterials = _materialsManager->getAcousticsMaterials(Acoustics::FITKAcousticsAbsMaterial::ISOSolid);
        bool b = true;
        IO:: VAOneXMLAdaptorMaterialIsosolid* adaptor{};

        // 循环处理每个材料
        for (const auto& material : FITKAcousticsMaterials)
        {
            if (!material) continue;

            // 使用适配器写入数据
            if(!adaptor)
            {
                adaptor = FITKIOADAPTORFACTORY->createT<IO::VAOneXMLAdaptorMaterialIsosolid>("VAOneXML", material);
                if (!adaptor)
                {
                    // 适配器创建失败，输出错误信息并返回失败
                    consoleMessage(3, "create Isosolid adaptor Error");
                    return false;
                }
            }

            // 创建各向同性固体节点
            rapidxml::xml_node<char>* node = createNodeElement(_node, "Isosolid");
            adaptor->setNode(node);
            adaptor->setDataObject(material);
            // 执行数据写入
            b &= adaptor->adaptW();
        }

        delete adaptor;
        adaptor = nullptr;
        // 返回操作成功的状态
        return b;
    }

    bool VAOneXMLAdaptorMaterial::readMaterialViscoElasticMaterial()
    {
        rapidxml::xml_node<char>* node = _node->first_node("ViscoElasticMaterial");

        // 判断节点是否存在
        if (!node) return true;

        bool b = true;
        IO:: VAOneXMLAdaptorMaterialViscoElastic* adaptor{};

        // 循环处理每个节点数据
        while (node)
        {
            Acoustics::FITKAcousticsMaterialsViscoElastic* mData = new Acoustics::FITKAcousticsMaterialsViscoElastic;
            if(!adaptor)
            {
                adaptor = FITKIOADAPTORFACTORY->createT<IO::VAOneXMLAdaptorMaterialViscoElastic>("VAOneXML", mData);
                if(!adaptor)
                {
                    delete mData;
                    mData = nullptr;
                    //读写器创建异常
                    consoleMessage(3,"create ViscoElasticMaterial adaptor Error");
                    return false;
                }
            }

            adaptor->setNode(node);
            adaptor->setDataObject(mData);
            b &= adaptor->adaptR();
            //根据名称获取对象
            auto m = _materialsManager->getDataByName(mData->getDataObjectName());
            if(!m)
            {
                //返回为空 插入mData
                _materialsManager->appendDataObj(mData);
            }
            else
            {
                //返回不为空， 覆盖数据
                m->copy(mData);
                delete mData;
            }

            node = node->next_sibling("ViscoElasticMaterial");
        }

        delete adaptor;
        adaptor = nullptr;
        //读取成功
        return b;
    }

    bool VAOneXMLAdaptorMaterial::writeMaterialViscoElasticMaterial()
    {
        // 获取粘弹性材料列表
        auto FITKAcousticsMaterials = _materialsManager->getAcousticsMaterials(Acoustics::FITKAcousticsAbsMaterial::ViscoElastic);
        bool b = true;
        IO:: VAOneXMLAdaptorMaterialViscoElastic* adaptor{};

        // 循环处理每个材料
        for (const auto& material : FITKAcousticsMaterials)
        {
            if (!material) continue;

            // 使用适配器写入数据
            if(!adaptor)
            {
                adaptor = FITKIOADAPTORFACTORY->createT<IO::VAOneXMLAdaptorMaterialViscoElastic>("VAOneXML", material);
                if (!adaptor)
                {
                    // 适配器创建失败，输出错误信息并返回失败
                    consoleMessage(3, "create ViscoElasticMaterial adaptor Error");
                    return false;
                }
            }

            // 创建粘弹性节点
            rapidxml::xml_node<char>* node = createNodeElement(_node, "ViscoElasticMaterial");
            adaptor->setNode(node);
            adaptor->setDataObject(material);
            // 执行数据写入
            b &= adaptor->adaptW();
        }

        delete adaptor;
        adaptor = nullptr;
        // 返回操作成功的状态
        return b;
    }
}
